home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-24 | 15.2 KB | 456 lines | [TEXT/R*ch] |
- (* ****************************************************** *)
-
- (* Make.sml *)
- (* 05Sep95 e *)
- (* 15Jun97 e -- modified to use second mosml for compiling;
- supports bootstrapping mosml142 *)
-
- open List BasicIO;
-
- (*
-
- load "Path";
- load "Process";
-
- val home =
- case Process.getEnv "PATH_TRANSLATED" of
- SOME n => Path.dir n
- | NONE => ":"
- ;
-
- load "Lexing";
- load "Nonstdio";
- load "Parsing";
- load "FileSys";
-
- chDir (home ^ "src:compiler:");
- load "Config";
- load "Hasht";
-
- chDir (home ^ "src:toolssrc:");
- load "Deppars";
- load "Deplex";
-
- chDir (home ^ "e_SML:");
- load "Mosmlrun";
-
- chDir home;
-
- *)
-
- (* portions stolen from... *)
-
- (* Mosmldep -- computing dependencies in a Moscow ML source directory. *)
-
- (* Lexer of stream *)
-
- fun createLexerStream (is : instream) =
- Lexing.createLexer (fn buff => fn n => Nonstdio.buff_input is buff 0 n)
- ;
-
- fun parsePhraseAndClear parsingFun lexingFun lexbuf =
- let val phr =
- parsingFun lexingFun lexbuf
- handle x => (Parsing.clearParser(); raise x)
- in
- Parsing.clearParser();
- phr
- end;
-
- val parseFile =
- parsePhraseAndClear Deppars.MLtext Deplex.Token;
-
- fun addExt s ext = s ^ "." ^ ext;
-
- (* now the new stuff... *)
-
- (* 1- use Mosmldep to find each source file's dependencies
- 2- build some data structures (see below)
- 3- make the transitive closure of the dependencies
- 4- sort the files in dependency order
- 5- process each file in turn
- checking modified times as documented below for function ensure
- and compiling out-of-date files
-
- data structures...
- after parsing: (objname,srcname,[objdeps],[moddeps]) called pd
- closedeps calls pdltoa to make...
- a hash table: objname -> index called hn
- and an array: index -> pd called ap
- and an array: index -> [indexes of objdeps] called di
- closedeps makes
- an array of indexes in dependency sorted order called oi
- and returns the value (n,hn,ap,di,oi)
- where n is the length of the arrays
- ensure uses n,hn,ap,di,oi to compile files needing it
-
- pd
- objname is the name of the object file
- .sml files generate .uo entry
- .sig files generate .ui entry
- srcname is the name of the file found in the directory
- objdeps is a list of object files depended upon
- dependency on a unit inserts
- <unit>.ui into deps if <unit>.sig exists
- otherwise <unit>.uo is inserted
- moddeps is a list of units (not in this directory) depended upon
-
- read (the file parser) keeps a hash table of previously generated pd
- it is keyed by srcname;
- the modTime of the file is kept and checked to insure accuracy
- this hashtable can be manually cleared with: reset_readht();
- *)
-
- val moolevel = ref 1;
-
- (* moolevel
- 0: no messages
- 1: error messages
- 2: compile messages
- 3: progress messages
- *)
-
- fun moo v s1 s2 = if !moolevel >= v then (print s1; print s2; print "\n") else ();
- fun muu v s = if !moolevel >= v then print s else ();
-
- fun pdltoa pdl =
- let val hn = Hasht.new 37 : (string, int) Hasht.t
- fun lp1 n r =
- if (null r) then n
- else let val (name,_,_,_) = (hd r)
- in Hasht.insert hn name n;
- lp1 (n+1) (tl r)
- end
- in
- let val q = lp1 0 pdl
- val ap = Array.array(q,("","",[""],[""]))
- val di = Array.array(q,[])
- fun lp2 n r =
- if (null r) then ()
- else let val (name,_,ns,_) = (hd r)
- in Array.update(ap,n,(hd r));
- Array.update(di,n,(List.map (Hasht.find hn) ns));
- lp2 (n+1) (tl r)
- end
- in
- lp2 0 pdl;
- (q,hn,ap,di)
- end
- end;
-
- fun closedeps pdl =
- let val (n,hn,ap,di) = pdltoa pdl
- val dp = Array.array (n, []) (* dependents *)
- val qd = Array.array (n, 0 ) (* dependencies *)
- fun initdeps (deps,x) =
- let fun idep m r =
- if (null r) then m
- else let val h = hd r
- in Array.update ( dp, h, x :: (Array.sub (dp, h)) );
- idep (m + 1) (tl r)
- end
- in Array.update (qd, x, idep 0 deps);
- x+1
- end
- val oi = Array.array (n, 0 )
- val qi = ref 0 (* queue in *)
- val ou = ref 0 (* queue out *)
- fun enque x = (Array.update ( oi, !qi, x ); qi := !qi + 1)
- fun pass1 i =
- if (i = n) then ()
- else let val x = Array.sub (qd, i)
- in if ( x = 0 ) then enque i else ();
- pass1 (i + 1 )
- end
- fun pass2 r =
- if (null r) then ()
- else let val h = hd r
- val x = Array.sub (qd, h) - 1
- in Array.update ( qd, h, x );
- if ( x = 0 ) then enque h else ();
- pass2 (tl r)
- end
- fun deque x = (pass2 (Array.sub (dp, x)); ou := !ou + 1)
- in
- moo 3 "\n" "Computing Dependencies";
- Array.foldl initdeps 0 di;
- pass1 0;
- while ( !ou < !qi ) do deque (Array.sub (oi, !ou));
- if (!ou = n)
- then ()
- else let val (nm,_,_,_) = Array.sub (ap,!ou)
- in moo 1 "Circularity involving: " nm;
- raise (Fail "circle"); ()
- end;
- (n,hn,ap,di,oi)
- end;
-
- fun read' pdl srcext objext filename =
- let val is = open_in (addExt filename srcext)
- val lexbuf = createLexerStream is
- val mentions = Hasht.new 37 : (string, unit) Hasht.t
- val names = parseFile lexbuf
- val objlist = ref []
- val modlist = ref []
- fun adddep s =
- if FileSys.access (addExt s "sig", []) then
- objlist := addExt s "ui" :: !objlist
- else if FileSys.access (addExt s "sml", []) then
- objlist := addExt s "uo" :: !objlist
- else (* libr or included dir files? *)
- modlist := s :: !modlist
- in
- close_in is;
- List.app (fn name => Hasht.insert mentions name ()) names;
- if srcext = "sml" andalso FileSys.access(addExt filename "sig", [])
- then Hasht.insert mentions filename () else ();
- Hasht.apply (fn name => fn _ => adddep name) mentions;
- pdl := ((addExt filename objext),
- (addExt filename srcext),
- !objlist,
- !modlist) :: !pdl
- end
- handle Parsing.ParseError _ => output(std_out, "Parseerror!\n");
-
- val readht = ref (Hasht.new 67
- : (string, (Time.time *
- (string * string * string list * string list)))
- Hasht.t);
-
- fun reset_readht _ =
- readht := (Hasht.new 67
- : (string, (Time.time *
- (string * string * string list * string list)))
- Hasht.t);
-
- fun read pdl srcext objext filename =
- let val sn = (addExt filename srcext)
- val mt = FileSys.modTime sn
- fun dit s = muu 3 s
- fun oops s =
- ( dit s;
- read' pdl srcext objext filename;
- Hasht.insert (!readht) sn (mt,(hd (!pdl))) )
- in
- let val (tm,pd) = Hasht.find (!readht) sn
- in
- case (Time.compare (tm,mt)) of
- EQUAL => ( dit "."; pdl := pd :: !pdl )
- | _ => oops ";"
- end
- handle _ => oops ":"
- end;
-
- fun checkf srcext genext base =
- let val gennam = (addExt base genext)
- val havgen = (FileSys.access (gennam,[]))
- in
- if havgen then ()
- else moo 2 " warning: " ((addExt base srcext) ^ " but no: " ^ gennam)
- end;
-
- fun processfile pdl filename =
- let val {base, ext} = Path.splitBaseExt filename
- val base' = Path.file base
- in
- case ext of
- SOME "sig" => read pdl "sig" "ui" base'
- | SOME "sml" => read pdl "sml" "uo" base'
- | SOME "grm" => (checkf "grm" "sml" base'; checkf "grm" "sig" base')
- | SOME "lex" => checkf "lex" "sml" base'
- | SOME "mlp" => checkf "mlp" "sml" base'
- | _ => ()
- end;
-
- (* ensure -- that a file is compiled if need be
- 1- if there is no object
- 2- if the mtime of the object is older than the epoch
- 3- if the mtime of the source is newer than mtime of the object
- 4- if the mtime of any dependency is newer than the mtime of the object
-
- the build order of the files is passed in oi
- trick: we keep the mtime of each object in an array, timarr, indexed
- by position in the initial list; since only files earlier in
- the list can be depended upon, only their times are needed, so
- mtimes of files are thereby memoized
- dependencies on units outside the target directory are also checked
- and memoized in a local hashtable
- *)
-
- val make_lib = ref "";
- val make_perv = ref "-P none";
- val make_path = ref [] : string list ref;
- val find_path = ref [] : string list ref;
-
- (* stolen from compiler/Mixture.sml *)
-
- fun cannot_find filename =
- raise (Fail ("Cannot find file "^filename))
- ;
-
- fun file_exists filename =
- FileSys.access (filename,[])
- ;
-
- fun find_in_path filename =
- if file_exists filename then
- filename
- else if Path.isAbsolute filename then
- cannot_find filename
- else
- let fun h [] =
- cannot_find filename
- | h (a::rest) =
- let val b = Path.joinDirFile { dir = a, file = filename } in
- if file_exists b then b else h rest
- end
- in h (!find_path) end
- ;
-
- (* *)
-
- fun perv_set set =
- make_perv := ("-P " ^ set)
- ;
-
- (*
- let open Mosmlrun in
- mosmlrun_compile "/StarMPW/ml/mosml142/lib/" "-P none" ["/StarMPW/ml/mosml142/src/compiler/"] "/StarMPW/ml/mosml142/src/compiler/Stack.sig"
- handle MosmlrunErr(n,s) => print s
- end;
- *)
-
- fun compile_ name =
- let open Mosmlrun
- in
- ( print "Compiling: "; print name; print "\n" ) ;
- mosmlrun_compile (!make_lib) (!make_perv) (!make_path)
- ((hd (!make_path)) ^ name)
- handle MosmlrunErr(n,s) => print s
- end
- ;
-
- fun ensure epoch (n,hn,ap,di,oi) =
- let val timarr = Array.array(n,Time.zeroTime)
- fun ftime x = Array.sub(timarr,x)
- val itimes = Hasht.new 37 : (string, Time.time) Hasht.t
- fun itime' m =
- let val uiname = (addExt m "ui")
- val prname = find_in_path uiname
- in moo 3 " checking: " m;
- FileSys.modTime prname
- end handle Fail s => (moo 1 " uncheck: " s; epoch)
- fun itime m = Hasht.find itimes m
- handle Subscript =>
- let val i = itime' m (* memoize! *)
- in Hasht.insert itimes m i; i end
- fun nxt z =
- if z >= n then ()
- else let val x = Array.sub(oi,z)
- val (objname,srcname,objdeps,moddeps) = Array.sub(ap,x)
- val deps = Array.sub (di,x)
- in
- if( FileSys.access (objname,[]) andalso
- let val otime = FileSys.modTime objname in
- Time.>(otime,epoch) andalso
- Time.>(otime,(FileSys.modTime srcname)) andalso
- (* this is conservative; too conservative if make is always used!
- (List.all (fn d => Time.>(otime,ftime d)) deps) andalso
- *)
- (List.all (fn d => Time.>=(otime,ftime d)) deps) andalso
- (List.all (fn d => Time.>(otime,itime d)) moddeps) andalso
- ( Array.update(timarr,x,otime); true )
- end )
- then moo 3 " ensuring: " objname
- else ( moo 2 "compiling: " objname;
- compile_ srcname;
- Array.update(timarr,x,FileSys.modTime objname) );
- nxt (z+1)
- end
- in nxt 0;
- moo 3 "" ""
- end;
-
- fun make oset stdlib includes fpath mpath =
- let open FileSys
- val _ = if !moolevel < 0 (* kludgy way to reset table *)
- then (reset_readht(); moolevel := (~ (!moolevel)))
- else ()
- val pdl = ref []
- val dir = openDir mpath
- val _ = chDir mpath
- fun read "" = ()
- | read f = ( processfile pdl f ; read (readDir dir) )
- val _ = ( read (readDir dir); closeDir dir; () )
- handle exn as OS.SysErr (msg, _) => (moo 1 msg ""; raise exn)
- val nhnapdioi = closedeps (!pdl)
- in
- make_lib := stdlib;
- make_path := (if stdlib <> ""
- then includes @ [stdlib]
- else includes);
- perv_set (if oset <> "" then oset else "default");
- find_path := fpath;
- ensure Time.zeroTime nhnapdioi
- end;
-
- (*
-
- moolevel := ~2;
-
- make "none" "/StarMPW/ml/mosml142/lib/"
- ["/StarMPW/ml/mosml142/src/compiler/"] []
- "StarMPW:ml:mosml142:src:compiler"
- ;
-
- make "none" "/StarMPW/ml/mosml142/lib/"
- ["/StarMPW/ml/mosml142/src/lex/", "/StarMPW/ml/mosml142/src/compiler/"]
- [] "StarMPW:ml:mosml142:src:lex"
- ;
-
- :lib:mosmllnk -stdlib /StarMPW/ml/mosml142/lib/ -P none -g -I /StarMPW/ml/mosml142/src/compiler/ -I /StarMPW/ml/mosml142/src/lex/ -noheader -o mosmllex /StarMPW/ml/mosml142/src/lex/Mainlex.uo
-
- make "none" "/StarMPW/ml/mosml142/lib/"
- ["/StarMPW/ml/mosml142/src/toolssrc/", "/StarMPW/ml/mosml142/src/compiler/"]
- [] "StarMPW:ml:mosml142:src:toolssrc"
- ;
-
- :lib:mosmllnk -stdlib /StarMPW/ml/mosml142/lib/ -P none -g -I /StarMPW/ml/mosml142/src/compiler/ -I /StarMPW/ml/mosml142/src/toolssrc/ -I /StarMPW/ml/mosml142/src/lex/ -noheader -o mosmltope /StarMPW/ml/mosml142/src/toolssrc/Maine.uo
-
- make "none -imptypes" "/StarMPW/ml/mosml142/src/mosmllib/"
- ["/StarMPW/ml/mosml142/src/mosmllib/"]
- [] "StarMPW:ml:mosml142:src:mosmllib"
- ;
-
- make "none" "/StarMPW/ml/mosml142/src/mosmllib/"
- ["/StarMPW/ml/mosml142/src/compiler/"]
- ["StarMPW:ml:mosml142:src:mosmllib:"]
- "StarMPW:ml:mosml142:src:compiler"
- ;
-
- make "none" "/StarMPW/ml/mosml142/src/mosmllib/"
- ["/StarMPW/ml/mosml142/src/lex/", "/StarMPW/ml/mosml142/src/compiler/"]
- ["StarMPW:ml:mosml142:src:mosmllib:"]
- "StarMPW:ml:mosml142:src:lex"
- ;
-
- make "none" "/StarMPW/ml/mosml142/src/mosmllib/"
- ["/StarMPW/ml/mosml142/src/toolssrc/",
- "/StarMPW/ml/mosml142/src/compiler/"]
- ["StarMPW:ml:mosml142:src:compiler:",
- "StarMPW:ml:mosml142:src:mosmllib:"]
- "StarMPW:ml:mosml142:src:toolssrc"
- ;
-
- :src:mosmllnk -stdlib /StarMPW/ml/mosml142/src/mosmllib/ -P none -g -I /StarMPW/ml/mosml142/src/compiler/ -I /StarMPW/ml/mosml142/src/toolssrc/ -I /StarMPW/ml/mosml142/src/lex/ -noheader -o mosmltope /StarMPW/ml/mosml142/src/toolssrc/Maine.uo
- :src:mosmllnk -stdlib /StarMPW/ml/mosml142/src/mosmllib/ -P none -g -I /StarMPW/ml/mosml142/src/compiler/ -I /StarMPW/ml/mosml142/src/lex/ -noheader -o mosmllex /StarMPW/ml/mosml142/src/lex/Mainlex.uo
- :src:mosmllnk -stdlib /StarMPW/ml/mosml142/src/mosmllib/ -P none -g -I /StarMPW/ml/mosml142/src/compiler/ -noheader -o mosmllink /StarMPW/ml/mosml142/src/compiler/Mainl.uo
-
- mosmllink.image -stdlib StarMPW:ml:mosml142:src:mosmllib: -P none -g -I StarMPW:ml:mosml142:src:compiler: -I StarMPW:ml:mosml142:src:toolssrc: -I StarMPW:ml:mosml142:src:lex: -noheader -o mosmltope StarMPW:ml:mosml142:src:toolssrc:Maine.uo
- mosmllink.image -stdlib StarMPW:ml:mosml142:src:mosmllib: -P none -g -I StarMPW:ml:mosml142:src:compiler: -I StarMPW:ml:mosml142:src:lex: -noheader -o mosmllex StarMPW:ml:mosml142:src:lex:Mainlex.uo
- mosmllink.image -stdlib StarMPW:ml:mosml142:src:mosmllib: -P none -g -I StarMPW:ml:mosml142:src:compiler: -noheader -o mosmllink StarMPW:ml:mosml142:src:compiler:Mainl.uo
-
- *)
-
- (* ****************************************************** *)
-